package com.colin.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: colin
 * @Create: 2023/2/28 18:14
 */
@RestController
@RefreshScope // 动态感知修改后的值
public class RefreshScopeController implements ApplicationListener<RefreshScopeRefreshedEvent> {

    @Value("${common.age}")
    String age;
    @Value("${common.name}")
    String name;

    @GetMapping("/common")
    public String hello() {
        return name+"，"+age;
    }

    /**
     * 定时任务每隔3s执行一次
     * 触发 @RefreshScope 执行逻辑会导致 @Scheduled 定时任务失效
     */
    @Scheduled(cron = "*/3 * * * * ?")
    public void execute() {
        System.out.println("定时任务正常执行，name = " + name + "，gae = " + age);
    }

    /**
     * 标注了注解 @RefreshScope 的 bean，在发生了 RefreshScopeRefreshedEvent 事件时，
     * 会清空掉 spring 容器缓存中的 RefreshScopeController 的 bean 对象，因此其定时任务也就失效了，
     * 若要使得定时任务重新生效，其中一种解决方案如下：
     * RefreshScopeController 需实现监听接口 ApplicationListener，监听 RefreshScopeRefreshedEvent 事件，
     * 当感知到 RefreshScopeRefreshedEvent 事件发生后，调用一下 RefreshScopeController 的任意方法，
     * 使 Spring 容器中重新生成 RefreshScopeController 的 bean 对象，从而使得这个对象的定时任务重新生效
     *
     * @param event the event to respond to
     */
    @Override
    public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
        this.execute();
    }
}
